//#include <kernel/multiboot.h>
#include <include/stdio.h>
#include <include/string.h>
#include <include/assert.h>

#include <kernel/monitor.h>
#include <kernel/console.h>
#include <kernel/proc.h>
#include <kernel/trap.h>
#include <kernel/test.h>

#include <mm/mm.h>

#include <include/memlayout.h>
#include <include/mmu.h>
#include <include/pic.h>

void
kmain(unsigned int magic, void *addr)
{
	// Before doing anything else,complete the ELF loading process
	// Clear the uninitialized data(BSS) section of out kernel.
	// This ensure that all static/global variables start out zero.
	extern uint8_t edata[],end[];
	memset(edata,0,end-edata);

	//init_video();
	cons_init();

	// starting....
	cprintf("This is a baby os....%d!!\n",31415926);

	// initialize the memory management module..
	mm_init();

	// initialize the process module..
	proc_init();

	// initialize the trap...
	init_idt();
	enable_irq(CLOCK_IRQ);

	__asm __volatile("sti");
	//__asm __volatile("ud2");
	
	proc_create((uint8_t *)test_A);
	proc_run(&procs[0]);
	// Drop into the kernel monitor.
	while (1)
		monitor(NULL);
}    

// below is some test processes...
void
test_A(void)
{
	int i;
	for (;;) {
		cprintf("hello,webee!\n");
	}
}



/*
 * Variable panicstr contains argument to first call to panic; used as flag
 * to indicate that the kernel has already called panic.
 */
static const char *panicstr;

/*
 * Panic is called on unresolvable fatal errors.
 * It prints "panic: mesg", and then enters the kernel monitor.
 */
void
_panic(const char *file, int line, const char *fmt,...)
{
	va_list ap;

	if (panicstr)
		goto dead;
	panicstr = fmt;

	va_start(ap, fmt);
	cprintf("kernel panic at %s:%d: ", file, line);
	vcprintf(fmt, ap);
	cprintf("\n");
	va_end(ap);

dead:
	/* break into the kernel monitor */
	while (1)
		monitor(NULL);
}

/* like panic, but don't */
void
_warn(const char *file, int line, const char *fmt,...)
{
	va_list ap;

	va_start(ap, fmt);
	cprintf("kernel warning at %s:%d: ", file, line);
	vcprintf(fmt, ap);
	cprintf("\n");
	va_end(ap);
}
